package com.example.rabbitdemo.message;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class ReliableConsumer {

    @RabbitListener(queues = "my.queue")
    public void handleMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
        log.info("接收到消息：{}", message);
        try {
            // 1. 执行核心业务逻辑（例如：处理订单、更新库存）
//            yourBusinessService.process(message);

            System.out.println("<UNK>" + message);
            Thread.sleep(100, TimeUnit.MICROSECONDS.ordinal());


            // 2. 业务处理成功，手动发送ACK确认
            channel.basicAck(deliveryTag, false); // 第二个参数false表示不批量确认
            log.info("消息处理成功，已ACK。 DeliveryTag: {}", deliveryTag);

        } catch (RuntimeException e) { // 明确的业务异常，通常重试无益
            log.error("业务处理失败，消息将被丢弃或转入死信队列。消息: {}, 错误: {}", message, e.getMessage());
            // 拒绝消息，并不重新入队（可根据需要配置死信队列）
            channel.basicNack(deliveryTag, false, false);
        } catch (Exception e) { // 网络中断、数据库暂时连不上等可能恢复的异常
            log.error("处理消息时发生可重试异常，消息将重新入队。消息: {}", message, e);
            // 拒绝消息，并让消息重新回到队列（等待重试）
            // 注意：结合spring.rabbitmq.listener.simple.retry配置，避免无限重试
            channel.basicNack(deliveryTag, false, true);
        }
    }
}